package com.senmiao.ssm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.senmiao.ssm.constants.MyConstants;
import com.senmiao.ssm.entity.*;
import com.senmiao.ssm.exception.MyException;
import com.senmiao.ssm.mapper.*;
import com.senmiao.ssm.pojo.vo.AdminShowListVo;
import com.senmiao.ssm.pojo.vo.RoleShowListVo;
import com.senmiao.ssm.service.CommonService;
import com.senmiao.ssm.service.SystemManagerService;
import com.senmiao.ssm.utils.EncryptUtils;
import com.senmiao.ssm.utils.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SystemManagerServiceImpl implements SystemManagerService {


    @Resource
    private CommonService commonService;

    @Resource
    private AdminMapper adminMapper;

    @Resource
    private AdminRoleMapper adminRoleMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private OperateLogMapper operateLogMapper;

    @Transactional
    @Override
    public Result createAdmin(String account, String username, String phone, String email, List<Integer> roleIds) {
        List<Admin> adminList = adminMapper.selectList(new QueryWrapper<Admin>().eq("account", account));
        if (adminList.size() > 0) {
            throw new MyException("用户名重复");
        }
        Admin admin = new Admin();
        admin.setAccount(account);
        admin.setUsername(username);
        admin.setPhone(phone);
        admin.setEmail(email);
        // 初始密码为账号
        String salt = EncryptUtils.generateSalt();
        String password = EncryptUtils.encryptPassword(account, salt);
        admin.setSalt(salt);
        admin.setPassword(password);
        // 默认是禁用状态
        admin.setDisable(1);
        admin.setIsDelete(0);
        admin.setCreateTime(new Date());
        int insert = adminMapper.insert(admin);
        if (insert > 0) {
            Integer adminId = admin.getId();
            for (Integer roleId : roleIds) {
                // 判断角色id是否存在
                Role role = roleMapper.selectOne(new QueryWrapper<Role>()
                        .eq("id", roleId).eq("is_delete", 0));
                if (role == null) {
                    throw new MyException("角色不存在");
                }
                // 生成管理员和角色的关系
                AdminRole adminRole = new AdminRole();
                adminRole.setAdminId(adminId);
                adminRole.setRoleId(roleId);
                adminRole.setAuthorityType(MyConstants.VISIT);
                adminRole.setIsDelete(0);
                adminRole.setCreateTime(new Date());
                // 保存到数据库
                int j = adminRoleMapper.insert(adminRole);
                if (j < 0) {
                    throw new MyException("保存管理员-角色信息异常");
                }
            }
        }
        return Result.ok();
    }

    @Override
    public Result updateAdminDisable(Integer adminId, Integer disable) {
        Admin admin = getAdminById(adminId);
        admin.setDisable(disable);
        admin.setModifiedTime(new Date());
        int update = adminMapper.update(admin, new QueryWrapper<Admin>().eq("id", adminId));
        if (update < 1) {
            throw new MyException("更新管理员表异常");
        }
        return Result.ok();
    }

    @Override
    public Result deleteAdmin(Integer adminId) {
        Admin admin = getAdminById(adminId);
        admin.setIsDelete(1);
        admin.setModifiedTime(new Date());
        int update = adminMapper.update(admin, new QueryWrapper<Admin>().eq("id", adminId));
        if (update < 1) {
            throw new MyException("删除管理员异常");
        }
        return Result.ok();
    }

    @Override
    public Result listAdmin(Integer pageNum, Integer limit) {
        Page<Admin> adminPage = adminMapper.selectPage(new Page<Admin>(pageNum, limit)
                , new QueryWrapper<Admin>().eq("is_delete", 0));
        ArrayList<AdminShowListVo> adminShowListVos = new ArrayList<>(adminPage.getRecords().size());
        for (Admin record : adminPage.getRecords()) {
            AdminShowListVo adminShowListVo = new AdminShowListVo();
            BeanUtils.copyProperties(record, adminShowListVo);
            adminShowListVos.add(adminShowListVo);
        }
        Result result = Result.ok();
        result.data("total", adminPage.getTotal())
                .data("pageNum", adminPage.getCurrent())
                .data("data", adminShowListVos);
        return result;
    }

    @Override
    public Result getAllRole() {
        List<Role> roleList = roleMapper.selectList(new QueryWrapper<Role>().eq("is_delete", 0));
        Result result = Result.ok();
        result.data("list", roleList).data("total", roleList.size());
        return result;
    }

    @Transactional
    @Override
    public Result updateAdminRole(Integer adminId, String username, String phone, String email, List<Integer> roleIds) {
        Admin admin = getAdminById(adminId);
        commonService.updateInfo(adminId, username, phone, email);
        checkRoleExist(roleIds);
        // 删除该管理员的所有角色
        AdminRole temp = new AdminRole();
        temp.setIsDelete(1);
        adminRoleMapper.update(temp,new QueryWrapper<AdminRole>().eq("admin_id",adminId));
        // 保存到管理员-角色 关系到数据库
        for (Integer roleId : roleIds) {
            AdminRole adminRole = adminRoleMapper.selectOne(new QueryWrapper<AdminRole>()
                    .eq("admin_id", adminId).eq("role_id", roleId));
            if (adminRole == null) {
                // 若数据库中无该条记录
                adminRole = new AdminRole();
                adminRole.setAdminId(adminId);
                adminRole.setRoleId(roleId);
                adminRole.setAuthorityType(MyConstants.VISIT);
                adminRole.setIsDelete(0);
                adminRole.setCreateTime(new Date());
                int insert = adminRoleMapper.insert(adminRole);
                if (insert < 1) {
                    throw new MyException("更新数据库异常");
                }
            } else {
                // 数据中有该条记录
                adminRole.setModifiedTime(new Date());
                if (adminRole.getIsDelete() != 0) {
                    adminRole.setIsDelete(0);
                    adminRoleMapper.update(adminRole, new QueryWrapper<AdminRole>()
                            .eq("admin_id", adminId).eq("role_id", roleId));
                }
            }
        }
        return Result.ok();
    }

    @Override
    public Result resetAdminPassword(Integer adminId) {
        Admin admin = getAdminById(adminId);
        String salt = EncryptUtils.generateSalt();
        String password = EncryptUtils.encryptPassword(admin.getAccount(), salt);
        admin.setSalt(salt);
        admin.setPassword(password);
        admin.setModifiedTime(new Date());
        int update = adminMapper.updateById(admin);
        if (update < 1){
            throw new MyException("更新数据库异常");
        }
        return Result.ok();
    }

    @Override
    public Result listRole(Integer pageNum, Integer limit) {
        Page<Role> rolePage = roleMapper.selectPage(new Page<>(pageNum, limit), new QueryWrapper<Role>().eq("is_delete", 0));
        ArrayList<RoleShowListVo> roleShowListVos = new ArrayList<>(rolePage.getRecords().size());
        for (Role record : rolePage.getRecords()) {
            RoleShowListVo roleShowListVo = new RoleShowListVo();
            BeanUtils.copyProperties(record,roleShowListVo);
            roleShowListVos.add(roleShowListVo);
        }
        Result result = Result.ok();
        result.data("list",roleShowListVos).data("total",rolePage.getTotal()).data("pageNum",rolePage.getCurrent());
        return result;
    }

    @Override
    public Result updateRoleComment(Integer roleId,String comment) {
        Role role = getRoleById(roleId);
        role.setComment(comment);
        role.setModifiedTime(new Date());
        int update = roleMapper.update(role, new QueryWrapper<Role>().eq("id", roleId));
        if (update < 1){
            throw new MyException("更新数据库异常");
        }
        return Result.ok();
    }

    @Transactional
    @Override
    public Result deleteRole(List<Integer> roleIds) {

        Integer count = roleMapper.selectCount(new QueryWrapper<Role>().in("id", roleIds).eq("is_delete", 0));
        if (count != roleIds.size()){
            throw new MyException("角色id不存在");
        }
        for (Integer roleId : roleIds) {
            Role role = getRoleById(roleId);
            role.setIsDelete(1);
            role.setModifiedTime(new Date());
            int update = roleMapper.updateById(role);
            if (update < 1){
                throw new MyException("更新数据库异常");
            }
        }
        return Result.ok();
    }

    @Override
    public Result createRole(String roleName, String comment) {
        Role role = new Role();
        role.setName(roleName);
        role.setComment(comment);
        role.setIsDelete(0);
        role.setCreateTime(new Date());
        int insert = roleMapper.insert(role);
        if (insert < 1){
            throw new MyException("添加到数据库异常");
        }
        return Result.ok();
    }

    @Override
    public Result listPermission(Integer pageNum, Integer limit) {
        Page<Permission> permissionPage = permissionMapper.selectPage(new Page<>(pageNum, limit),null);
        return Result.ok().data("list",permissionPage.getRecords())
                .data("total",permissionPage.getTotal()).data("pageNum",permissionPage.getCurrent());
    }

    @Override
    public Result listLoginAndLogoutLog(Integer pageNum, Integer limit) {
        ArrayList<Integer> types = new ArrayList<>();
        types.add(0);
        types.add(1);
        Page<OperateLog> operateLogPage = operateLogMapper.listLog(new Page<>(pageNum, limit), types);
        Result result = Result.ok();
        result.data("list",operateLogPage.getRecords())
                .data("total",operateLogPage.getTotal())
                .data("pageNum",operateLogPage.getCurrent());
        return result;
    }

    @Override
    public Result getAllPermission() {
        return Result.ok().data("list",permissionMapper.selectList(null));
    }

    /**
     * 通过id获取管理员记录，若不存在则抛出异常
     *
     * @param adminId
     * @return
     */
    private Admin getAdminById(Integer adminId) {
        Admin admin = adminMapper.selectOne(new QueryWrapper<Admin>()
                .eq("id", adminId).eq("is_delete", 0));
        if (admin == null) {
            throw new MyException("管理员id不存在");
        }
        return admin;
    }

    /**
     * 检查角色是否存在
     *
     * @param roleIds
     */
    private void checkRoleExist(List<Integer> roleIds) {
        Integer count = roleMapper.selectCount(new QueryWrapper<Role>().in("id", roleIds).eq("is_delete", 0));
        if (count != roleIds.size()) {
            throw new MyException("角色列表已刷新，请刷新页面重新进行操作");
        }
    }

    /**
     * 根据id获取角色
     * @param roleId
     * @return
     */
    private Role getRoleById(Integer roleId){
        Role role = roleMapper.selectOne(new QueryWrapper<Role>().eq("id", roleId).eq("is_delete", 0));
        if (role == null){
            throw new MyException("角色id不存在");
        }
        return role;
    }

}